package com.linkoog.devtools.http.parser.spring.handler;

import com.intellij.psi.*;
import com.linkoog.devtools.http.common.HttpMethod;
import com.linkoog.devtools.http.parser.spring.common.SpringConstants;
import com.linkoog.devtools.utils.PsiClassUtils;
import com.linkoog.devtools.utils.PsiMethodUtil;
import org.jetbrains.annotations.NotNull;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class SpringHttpMethodHandler {



    public List<HttpMethod> parseHttpMethod(@NotNull PsiMethod psiMethod){
        List<HttpMethod> result = new ArrayList<>();

        PsiAnnotation methodPsiAnnotation = PsiMethodUtil.parseMethodAnnotation(psiMethod, SpringConstants.METHOD_ANNOTATION_LIST, true);
        String methodPsiAnnotationName = methodPsiAnnotation.getQualifiedName();
        SpringConstants.MappingEnum mappingAnnotationEnum = SpringConstants.MappingEnum.valueOfQualifiedName(methodPsiAnnotationName);
        if (mappingAnnotationEnum != null){
            result.add(mappingAnnotationEnum.getHttpMethod());
            return result;
        }else if (SpringConstants.REQUEST_MAPPING.equals(methodPsiAnnotationName)){
            PsiAnnotationMemberValue psiAnnotationMemberValue = methodPsiAnnotation.findDeclaredAttributeValue("method");
            if (psiAnnotationMemberValue == null){
                result.add(HttpMethod.POST);
                return result;
            }

            if (psiAnnotationMemberValue instanceof PsiArrayInitializerMemberValue){
                final PsiArrayInitializerMemberValue psiArrayInitializerMemberValue = (PsiArrayInitializerMemberValue)psiAnnotationMemberValue;
                final PsiAnnotationMemberValue[] psiAnnotationMemberValues = psiArrayInitializerMemberValue.getInitializers();
                for (PsiAnnotationMemberValue annotationMemberValue : psiAnnotationMemberValues) {
                    parsePsiAnnotationMemberValue(result, annotationMemberValue);
                }
            } else {
                parsePsiAnnotationMemberValue(result, psiAnnotationMemberValue);
            }

            if (!result.isEmpty()){
                return result;
            }
        }

        result.add(HttpMethod.POST);
        return result;
    }

    private void parsePsiAnnotationMemberValue(List<HttpMethod> result, PsiAnnotationMemberValue psiAnnotationMemberValue){
        PsiReference psiReference = psiAnnotationMemberValue.getReference();
        if (psiReference == null) return;

        PsiElement psiElement = psiReference.resolve();
        if (psiElement == null) return;
        result.add(HttpMethod.valueOf(psiElement.getText()));
    }

}
